import React, { useCallback } from 'react';
import * as THREE from 'three';
import { SceneUtils } from 'three/examples/jsm/utils/SceneUtils.js';
import Stats from 'stats-js';
import * as dat from 'dat.gui';

export default function Index() {
  const refWrap = React.createRef();
  const refCanvas = React.createRef();
  const [camera, setCamera] = React.useState();
  const [renderer, setRenderer] = React.useState();
  const [plane, setPlane] = React.useState();
  const [scene, setScene] = React.useState();
  // 动画帧数
  const initStats = () => {
    const stats = new Stats();
    stats.setMode(0);
    stats.domElement.style.position = 'absolute';
    stats.domElement.style.left = '0';
    stats.domElement.style.top = '0';
    document.body.appendChild(stats.domElement);
    return stats;
  };
  // 添加立方体
  const addCube = () => {
    const cubeSize = Math.ceil(Math.random() * 3);
    const cubeGeometry = new THREE.SphereGeometry(2, 2, 3);
    const cubeMaterial = new THREE.MeshBasicMaterial({ color: 'red', opacity: 0.6, transparent: true });
    const cubeMaterial2 = new THREE.MeshLambertMaterial({ color: 0x000000, wireframe: true });
    const cube = SceneUtils.createMultiMaterialObject(cubeGeometry, [cubeMaterial, cubeMaterial2]);
    // const a = new THREE.Mesh(cubeGeometry, cubeMaterial);
    // const wireframe = new THREE.WireframeGeometry(cubeGeometry);
    // var cube = new THREE.LineSegments(wireframe);
    // const cube = new THREE.WireframeHelper(a, 0x000000);
    // console.log(cube);
    cube.castShadow = true;
    cube.name = 'cube-' + scene.children.length;
    cube.position.x = -30 + Math.round(Math.random() * plane.geometry.parameters.width);
    cube.position.y = Math.round(Math.random() * 5);
    cube.position.z = -10 + Math.round(Math.random() * plane.geometry.parameters.height);
    cube.rotation.x = Math.random();
    cube.rotation.y = Math.random();
    cube.rotation.z = Math.random();
    scene.add(cube);
    // console.log(scene);
  };
  // 移除立方体
  const removeCube = () => {
    const childrens = scene.children;
    const last = childrens[childrens.length - 1];
    if (last instanceof THREE.Mesh) {
      scene.remove(last);
    }
  };

  const init = () => {
    // const stats = initStats();
    refCanvas.current.width = refWrap.current.clientWidth;
    refCanvas.current.height = refWrap.current.clientHeight;
    const scene = new THREE.Scene();
    // const camera = new THREE.PerspectiveCamera(
    //   45,
    //   refCanvas.current.width / refCanvas.current.height,
    //   0.1,
    //   1000
    // );
    const camera = new THREE.OrthographicCamera(
      refCanvas.current.width / -16,
      refCanvas.current.width / 16,
      refCanvas.current.height / 16,
      refCanvas.current.height / -16,
      -200,
      500
    );
    camera.position.x = -30;
    camera.position.y = 20;
    camera.position.z = 30;
    camera.lookAt(scene.position);

    const renderer = new THREE.WebGLRenderer({ canvas: refCanvas.current });

    renderer.setClearColor(0xeeeeee, 1.0);
    renderer.setSize(refCanvas.current.width, refCanvas.current.height);
    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap
    // 坐标系
    const axes = new THREE.AxesHelper(20);
    scene.add(axes);
    // 面板
    const planGeometry = new THREE.PlaneGeometry(60, 20, 1, 1);
    const planeMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff });
    const plane = new THREE.Mesh(planGeometry, planeMaterial);
    plane.rotation.x = -1.5;
    plane.receiveShadow = true;
    // console.log(plane)
    scene.add(plane);
    // 环境光
    const ambientLight = new THREE.AmbientLight(0x0c0c0c);
    scene.add(ambientLight);
    // 灯光
    // 添加光
    const spotLight = new THREE.SpotLight(0xffffff);
    spotLight.position.set(-40, 60, -20);
    spotLight.castShadow = true;
    scene.add(spotLight);
    // 添加雾化效果
    scene.fog = new THREE.Fog(0xffffff, 0.015, 100);
    // scene.overrideMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff });

    // 渲染
    // addCube(scene, plane);
    renderer.render(scene, camera);
    const begin = () => {
      requestAnimationFrame(() => {
        renderer.render(scene, camera);
        begin();
      });
    };
    begin();

    setCamera(camera);
    setRenderer(renderer);
    setScene(scene);
    setPlane(plane);
  };

  React.useEffect(() => {
    init();
  }, []);

  React.useEffect(() => {
    const onResize = () => {
      if (refWrap.current) {
        camera.aspect = refWrap.current.clientWidth / refWrap.current.clientHeight;
        renderer.setSize(refWrap.current.clientWidth, refWrap.current.clientHeight);
        camera.updateProjectionMatrix();
      }
    };
    window.addEventListener('resize', onResize, false);
    return () => {
      window.removeEventListener('resize', onResize, false);
    };
  }, [camera]);

  return (
    <div ref={refWrap} style={{ width: '100%', height: '100%' }}>
      <canvas ref={refCanvas}></canvas>
      <div style={{ position: 'absolute', top: 0, right: 0 }}>
        <button onClick={addCube}>添加</button>
        <button onClick={removeCube}>移除</button>
      </div>
    </div>
  );
}
